using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;

namespace CSharpXDL
{
    class DownLoad
    {
        String url;
        String fName;
        volatile long thread_total;
        String[] args;
        File file;
        FileChannel channel;
        File bpr;
        Rate rate;
        Map<Character, Long> bprMap = new HashMap<Character, Long>();
        FileStream bprser;
        ArrayList<BlockDownloader> bdls;
      
        public ArrayList<BlockDownloader> Bdls
        {
            get { return bdls; }
            set { bdls = value; }
        }

        public DownLoad(String[] args)
        {
		    this.args=args;
	    }

	
	void complete(char fName) {
		lock (this) {
			--thread_total;
			System.Console.WriteLine(fName + " " + new Date().toLocaleString()
					+ ""+" download completed! There are "+thread_total+" downloading");
			if (thread_total == 0){
				try {
					channel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				System.Console.WriteLine(args[1]+" is download completed");
				//System.exit(0);
				
			}
				//merge();
		}
	}


        ArrayList<BlockDownloader> download()  {
		
		bdls = new ArrayList<BlockDownloader>();
		thread_total = 1;

		String[] urls=args[0].split("`");

		int urlsL = urls.length;
		long length = length(urls[0]);
		if (args.length > 2)
			thread_total = Long.parseLong(args[2]);
		long mod = length % thread_total;
		long partial = length / thread_total;
	//	bpr= File.Open(args[1]+".bpr",FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
		try {
			bprser= File.Open(args[1]+".bpr",FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
			//bprser.
			while(true)
				bprMap.put(bprser.readChar(),bprser.readLong());
			
		} catch (Exception e) {
            Console.WriteLine(e.StackTrace);
			// TODO: handle exception
		}
		file=new File(args[1]);
		FileStream dlFile = File.Open(args[1],FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);;
		dlFile.SetLength(length);
		
		
		BlockDownloader downloader = new BlockDownloader(this,urls[0], 'A', 0, partial);
		list.add(downloader);
		for (int i = 1; i < thread_total; i++) {
			long p = partial * (i);
			if (i == thread_total - 1) {
				downloader = new BlockDownloader(this,urls[i%urlsL], (char)('A'+i),
						p, partial + mod);
			} else {
				
				downloader = new BlockDownloader(this,urls[i%urlsL], (char)('A'+i),
						p, partial);
			}
			list.add(downloader);
			
		}
		rate=new Rate(this,list,length);
		start();		
		return list;
	}


    public long length(String url1) {
		
		try {

            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url1);


            if (httpRequest.HaveResponse)
            {
              Console.WriteLine(httpRequest.GetResponse().Headers);
              return  httpRequest.GetResponse().ContentLength;
            }
            else
            {
                Console.WriteLine("StatusCode " + httpRequest.GetResponse().StatusCode);
                return 0;
            }
            
          
		} catch (Exception e) {
			if(1==1)
			throw new Exception(e);
		} 

		return 0;

	}
    long getBpr(char key){
		lock (this) {
			Long p=bprMap.get(key);
			return p==null ? 0:p.longValue();
		}
	}


        void start()
        {
            foreach(){}

        }

    }
}
